CH06-图像变换

1 缩放变换

dst = cv2.resize(src, dsize = None, fx = None, fy = None, interpolation = None)

参数 说明
src 原图
dst 输出的图像
dsize 输出图像的大小
fx x 轴方向的缩放因子
fy y轴方向的缩放因子
interpolation 缩放方法
cv2.INTER_NEAREST : 最近邻插值法
cv2.INTER_LINEAR : 双线性插值法(默认)
cv2.INTER_AREA : 基于局部像素点的重采样
cv2.INTER_CUBIC : 基于 4 像素×4 像素邻域的 3 次插值法
cv2.INTER_LANCZOS4 : 基于 8 像素 × 8 像素邻域的 Lanczos 插值

进行缩小处理时推荐使用cv2.INTER_AREA,进行扩大处理时推荐使用cv2.INTER_LINEAR

函数中的输出图像参数和 fx,fy两个缩放因子只选择设置一项

# 第一种方法
res = cv2.resize(img, None, fx = 2, fy = 2, interpolation = cv2.INTER_CUBIC)

# 第二种方法
height, width = img.shape[:2]
res = cv2.resize(img, (2*width, 2*height), interpolation = cv2.INTER_CUBIC)

2. 平移变换

dst = cv2.warpAffine(src, M, dsize)

参数 说明
dst 输出图像
src 原图像
M 对应矩阵
dsize 输出图像的大小,为元祖形式(img.shape[1], img.shape[0])
img = cv2.imread('img/CH05-1.jpg')
M = np.float32([[1, 0, 100],[0,1,50]])
x = img.shape[0]
y = img.shape[1]
out = cv2.warpAffine(img,M,(y,x))
# 图形缩放,图形向右平移 100 像素点,向下平移 50 个像素点
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', int(y/4),int(x/4))
cv2.imshow('img',out)
cv2.waitKey(0)
cv2.destroyAllWindows()

3. 旋转变换

M = cv2.getRotationMatrix2D(center, angle, scale)

参数 说明
center 旋转中心,为元祖形式
angle 旋转角度,为角度制(非弧度制)
scale 旋转后的缩放因子
M 得到的任意点旋转矩阵
img = cv2.imread('img/CH05-1.jpg')
rows = img.shape[0]
cols = img.shape[1]
M = cv2.getRotationMatrix2D((int((cols)/2.0),int((rows)/2.0)), 45, 0.5)
out = cv2.warpAffine(img, M, (cols, rows))
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', int(cols/3),int(rows/3))
cv2.imshow('img', out)
cv2.waitKey(0)
cv2.destroyAllWindows()

4. 仿射变换

M = cv2.getAffineTransfrom(src, dst)

参数 说明
M 进行仿射变换的矩阵
src 输入图像中的 3 个点的坐标
dst 3个点在输出图像中对应的坐标
# 读取图像
img = cv2.imread('img/CH05-1.jpg')
rows = img.shape[0]
cols = img.shape[1]
# 设置对应点
pts1 = np.float32([[50, 50],[200, 50],[50, 200]])
pts2 = np.float32([[10, 100],[200, 50],[100, 250]])
# 仿射变换
M = cv2.getAffineTransform(pts1, pts2)
out = cv2.warpAffine(img, M, (cols, rows))
# 显示图像
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', int(cols/3), int(rows/3))
cv2.imshow('img', out)
cv2.waitKey(0)
cv2.destroyAllWindows()

5. 透视变换

仿射变换和透视变换的区别:

  • 仿射变换虽然会改变原图像的外部形状,但是原图像中相互平行的线在输出图像中依旧保持平行
  • 透视变换中,输入图像中的平行线可能不再平行,不平行的线可能会变平行

平移变换、旋转变换、仿射变换对应的矩阵是 2×3 的矩阵,而透视变换对应的是 3×3 的矩阵

为了获得透视变换的矩阵,我们需要在输入图像上找到 4 个点及其在输出图像中对应的位置坐标,且这 4 个点需要满足任意 3 个点都不能共线

M = cv2.getPerspectiveTransform(src,dst)

参数 说明
src 输入图像
M 透视变换矩阵
dsize 输出图像的大小,形式为元祖
dst 输出图像

cv2.warpPerspective(src, M, dsize)

参数 说明
src 输入图像
M 透视变换矩阵
dsize 输出图像的大小,形式为元祖
dst 输出图像
img = cv2.imread('img/CH05-1.jpg')
rows = img.shape[0]
cols = img.shape[1]
# 设置对应点
pts1 = np.float32([[56, 65],[368, 52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
# 透视变换
M = cv2.getPerspectiveTransform(pts1, pts2)
out = cv2.warpPerspective(img, M, (cols, rows))
# 显示图像
cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cv2.resizeWindow('img', int(cols/3), int(rows/3))
cv2.imshow('img', out)
cv2.waitKey(0)
cv2.destroyAllWindows()